﻿package com.htmlparser;

import java.io.FileOutputStream;
import java.util.Calendar;
import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.filters.NodeClassFilter;
import org.htmlparser.filters.TagNameFilter;
import org.htmlparser.nodes.TextNode;
import org.htmlparser.tags.BodyTag;
import org.htmlparser.tags.Div;
import org.htmlparser.tags.FormTag;
import org.htmlparser.tags.InputTag;
import org.htmlparser.tags.LabelTag;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.tags.OptionTag;
import org.htmlparser.tags.ParagraphTag;
import org.htmlparser.tags.SelectTag;
import org.htmlparser.tags.Span;
import org.htmlparser.tags.TableColumn;
import org.htmlparser.tags.TableRow;
import org.htmlparser.tags.TableTag;
import org.htmlparser.tags.TextareaTag;
import org.htmlparser.util.NodeList;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

import com.moa.ActionServlet;
import com.pc.util.http.PCHttp;
import java.util.Hashtable;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~测试输出~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public class MyParse62 {
	// 接受boss传递的inputHtml_path(需要在不完整路径前添加的路径)，有的方法(getContent以外)需要inputHtml_path这个参数
	public static String path = "";

	// //接受boss传递的inputHtml(原OA页面的html代码)，有的方法(getContent以外)需要inputHtml这个参数
	private static String html = "";

	// 解析结果的输出路径，有时需要在本地查看一下解析的结果
	private static String output = "e:\\MyParse62.xml";

	// 解析器parser的编码
	private static String encoding = "GBK";

	// name: 登录用户名，由ActionServlet传递过来
	private static String name = "";

	// hiddens_id: 数组hiddens的下标
	public static int hiddens_id = 0;

	// 由当前用户名和当前时间组成的唯一键
	public static String key;

	// 存放hidden的键值对，键--key，值--hiddens[0]
	public static Hashtable hashtalbe = new Hashtable();

	// radio_id: 遍历radio的标记，防止重复遍历
	static boolean radio_flag = false;

	// 返回给手机端的字符串
	static String htmltext = "";

	// form表单的提交按钮的url
	static String smt_url = "";

	// 手机端请求的路径
	public static String mobile_path = "";

	// 提交给server端的路径
	public static String server_path = "";

	//
	static Element radio = null;

	// radio的下标
	static int radio_index = 0;

	// hidden的下标
	static int hidden_index = 0;

	public static int radio_count = 0;
	public static int radio_id = 0;

	//存放由所有hidden的键值对拼成的字符串
	public static String allHiddens = "";

	// 存放由JavaScript赋值的hidden的键值对
	public static Hashtable hiddens = new Hashtable();
	public static String[] hiddenNames = new String[50];
	
	//TODO 字符串缓存，分页
	public static String[] text_pages = null;
	
	public static void main(String[] args) {
		System.out.println();
		try {
			// getContent();
			PCHttp.login("mashenghai", "USERNAME=mashenghai&PASSWORD=", 0,"/logincheck.php", "UTF-8");
			//String[] inputHtml = PCHttp.sendGet("mashenghai",null,"/general/workflow/list/input_form?MENU_FLAG=&RUN_ID=80&FLOW_ID=32&PRCS_ID=1&FLOW_PRCS=1","GBK");
			
			//---/general/workflow/list/print?RUN_ID=83&FLOW_ID=32 
			String[] inputHtml = PCHttp.sendGet("mashenghai",null,"/general/workflow/list/print?RUN_ID=83&FLOW_ID=32","GBK");
			getContent(inputHtml[0], inputHtml[1], true);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	// 提取网页中的表格table
	public static String getContent(String inputHtml_content,
			String inputHtml_path, boolean radio_access) throws Exception {
		
		System.out.println("");
		System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
		System.out.println("");
		System.out.println("boss 传的path：" + inputHtml_path);
		System.out.println("");
		System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
		System.out.println("");
		
		// 第二次访问页面时，把radio_count和radio_id置零，以免出现访问radio为空
		if (radio_access == true) {
			radio_count = 0;
			radio_id = 0;
		}

		System.out.println("");
		System.out.println("=================== XML 文档生成开始 ====================");
		System.out.println("               #################################          ");
		System.out.println("");

		Calendar ca = Calendar.getInstance();
		String longtime = String.valueOf(ca.getTimeInMillis());

		// 从ActionServlet得到当前登录的用户名
		name = ActionServlet.name;
		key = name + longtime;
		ActionServlet.setKey(key);

		// 手机每次访问时把radio_flag置为true，但本次访问，第一次解析radio以后置为false
		radio_flag = radio_access;

		// inputHtml_path : 需要在不完整路径前添加的路径
		path = inputHtml_path;

		System.out.println("");
		System.out.println("=================== 原OA的内容开始。。。。。。=================");
		System.out.println("");
		System.out.println(inputHtml_content);
		System.out.println("");
		System.out.println("=================== 原OA的内容结束！=================");
		System.out.println("");

		// 去掉输入字符串里的alert,<b>,<span>,<p>等标签
		/*************************************************************************************/
		html = Util.filterString(inputHtml_content);
		//html = inputHtml_content;
		
//		System.out.println("");
//		System.out.println("=================== 过滤后的内容开始。。。。。。=================");
//		System.out.println("");
//		System.out.println(html);
//		System.out.println("");
//		System.out.println("=================== 过滤后的内容结束！=================");
//		System.out.println("");
		
		/*************************************************************************************/

		JavaScript_parser.path = path;
		JavaScript_parser.html = html;
		Input.html = html;

		// 计算出radio_count
		Input.getRadio();
		System.out.println("radio_count==" + radio_count + "==");
		
		//TODO 获取所有隐藏域
		allHiddens = Input.getHidden();
		// TODO 防止数组hiddenNames越界，每访问完一次Input的getHidden()，就把Input的hidden_id置零
		Input.hidden_id = 0;
//		for (int i = 0; (i < hiddens.size()) && (i < hiddenNames.length)
//				&& (hiddenNames[i] != null); i++) {
//			System.out.println("hiddenNames[" + i + "]==" + hiddenNames[i]);
//			System.out.println("hiddens[" + hiddenNames[i] + "]###" + hiddens.get(hiddenNames[i]) + "###");// hiddenNames[i]
//		}
		
		
		//TODO JavaScript里面隐藏域的赋值
		//处理JavaScript里面的hidden赋值,主要是字符串替换和赋值
		//html = 
			Util.doJSHidden(html, hiddens);
	  
		JavaScript_parser.path = path;
		JavaScript_parser.html = html;
		Input.html = html;
		
		// 当前页面包含frameset
		if ((html.indexOf("frameset") > 0) || (html.indexOf("FRAMESET") > 0)) {
			htmltext = Frameset.doFrame(html, encoding, path, name);
			
			return htmltext;
			
		} else { // 当前页面不包含frameset
			// 提取table
			Parser table_parser = new Parser();
			table_parser.setInputHTML(html);
			table_parser.setEncoding(encoding);
			TagNameFilter tableFilter = new TagNameFilter("table");
			NodeList tableList = table_parser.extractAllNodesThatMatch(tableFilter);

			// 提取单独的div
			Parser div_parser = new Parser();
			div_parser.setInputHTML(html);
			div_parser.setEncoding(encoding);
			NodeFilter divFilter = new NodeClassFilter(Div.class);
			// TagNameFilter divFilter = new TagNameFilter("div");
			NodeList divList = div_parser.extractAllNodesThatMatch(divFilter);

			Parser form_parser = new Parser();
			form_parser.setInputHTML(html);
			form_parser.setEncoding(encoding);
			TagNameFilter formFilter = new TagNameFilter("form");
			NodeList formList = form_parser.extractAllNodesThatMatch(formFilter);

			Parser input_parser = new Parser();
			input_parser.setInputHTML(html);
			input_parser.setEncoding(encoding);
			TagNameFilter inputFilter = new TagNameFilter("input");
			NodeList inputList = input_parser
					.extractAllNodesThatMatch(inputFilter);
			// System.out.println("inputList==" + inputList + "==");

			Element data = new Element("data");
			Document document = new Document(data);

			if (tableList != null) {
				for (int i = 0; i <= tableList.size(); i++) {
					if (tableList.elementAt(i) instanceof TableTag) {

						// 过滤嵌套在div或者table里的table，以免解析出重复的talbe
						Boolean bDiv = (tableList.elementAt(i).getParent() instanceof Div);
						Boolean bTableColumn = ((tableList.elementAt(i).getParent() instanceof TableColumn));
						Boolean bFormTag = (tableList.elementAt(i).getParent() instanceof FormTag);
						Boolean bFormTag2 = (tableList.elementAt(i).getParent().getParent() instanceof Div);

						if (!bDiv && !bTableColumn && !bFormTag && !bFormTag2) {
							Element table = getTable((TableTag) (tableList.elementAt(i)));
							data.addContent(table);
						}
					}
				}
			}

			// 提取没有嵌套在table里的Div
			if (divList != null) {
				for (int i = 0; i < divList.size(); i++) {
					// divNode: 某个没有嵌套在table里的div
					Node divNode = divList.elementAt(i);
					if ((divNode != null) && (divNode instanceof Div)
							&& (divNode.getParent() instanceof BodyTag)) {
						// System.out.println("divNode=================");
						// System.out.println("(divNode.getParent() instanceof
						// BodyTag)===="+(divNode.getParent() instanceof
						// BodyTag));
						NodeList divChildrenList = divNode.getChildren();
						AllTags.doAllTags(divChildrenList, data);
					}
				}
			}

			// 提取单独的form ，即没有嵌套在table里面的form
			if (formList != null) {
				int index = 0;
				for (int i = 0; i < formList.size(); i++) {
					Node formNode = formList.elementAt(i);

					if (formNode instanceof FormTag
							&& (formNode.getParent() instanceof BodyTag)) {
						index++;
						Element form = getForm((FormTag) formNode);
						data.addContent(form);
					}
				}
			}

			if (inputList != null) {
				for (int i = 0; i < inputList.size(); i++) {
					Node inputNode = inputList.elementAt(i);

					if (inputNode instanceof InputTag
							&& (inputNode.getParent() instanceof BodyTag)) {
						Element input = Input.getInput((InputTag) inputNode,
								null);
						if (input != null) {
							data.addContent(input);
						}
						
					}
				}
			}

			Format format = Format.getPrettyFormat();
			format.setEncoding("utf-8");
			XMLOutputter outp = new XMLOutputter(format);
			outp.output(document, new FileOutputStream(output)); // 输出XML文档

			htmltext = Util.doc2String(data);

			System.out.println("");
			System.out.println("                  #################                     ");
			System.out.println("=================== XML 文档生成完毕！=================");
			System.out.println("");
			System.out.println("");
			System.out.println("");
			System.out.println("=================== 解析后的内容开始。。。。。。=================");
			System.out.println("");
			System.out.println(htmltext);
			System.out.println("");
			System.out.println("=================== 解析后的内容结束！=================");

			// 把隐藏域的键值对拼成的字符串放入hashtable中
			if (allHiddens.length() > 0) {
				String value2 = allHiddens.toString().substring(0,
						allHiddens.toString().length() - 1);// 去掉字符串的最后一个&
				// System.out.println("value2==" + value2 + "==");
				hashtalbe.put(key, value2);
			}

			// 为了在取出value2之后能

			return htmltext.replaceAll("&amp;nbsp", "");
		}

	}

	// 表格table
	public static Element getTable(TableTag table) {
		TableTag innerTable = table;
		TableRow[] rows = innerTable.getRows();
		Element Inner_table = new Element("T");

		if (rows != null) {
			System.out.println("");
			// System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~rows.length="+rows.length+"~~~~~~~~~~~~~~~~~~~~~~");
			// System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~rows[0]="+rows[0]+"~~~~~~~~~~~~~~~~~~~~~~");
			System.out.println("");
			Inner_table.setAttribute("r", String.valueOf(rows.length));
			Inner_table.setAttribute("c", String
					.valueOf(rows[0].getColumns().length));

			// 遍历所有行
			for (int j = 0; j < rows.length; j++) {// tr
				TableRow row = (TableRow) rows[j];

				// 取得当前行的所有列
				TableColumn[] columns = row.getColumns();

				// 遍历当前列的所有子节点
				for (int k = 0; k < columns.length; k++) {// td
					Element td = new Element("d");
					td.setAttribute("r", String.valueOf(j));
					td.setAttribute("c", String.valueOf(k));

					// 第j行第k列下面的内容
					// nodeList2:当前列的所有子节点的集合?
					NodeList nodeList2 = columns[k].getChildren();
					if (nodeList2 != null) {
						td = AllTags.doAllTags(nodeList2, td);
					}// td

					// if((td.getText() != null)&& !(td.getText().equals(""))){
					Inner_table.addContent(td);
					// }
				}
			}// tr
		}
		return Inner_table;
	}

	// 提取超链接
	public static Element getLink(LinkTag linkTag) {
		LinkTag link = linkTag;
		Element a = new Element("a");

		String href = link.getAttribute("href");
		String jsResult = "";
		if (link.isJavascriptLink()) {

			if ((href != null) && !(href.equals("")) && !(href.equals("#"))
					&& (href.indexOf("window") == -1)
					&& (href.indexOf("document") == -1)) {
				String temp = href.split(":")[1].replace(";", "");
				if (temp.indexOf(".") == -1) {
					System.out.println("");
					System.out.println("【getLink--isJavascriptLink()--function】这个超链接<a>里没有window，也没有点");
					String[] args = Util.getHrefParameters(href);
					String jsMethod = Util.getHrefMethod(href);

					// 判断参数是否为数字
					// 防止参数为空时，抛出数据转换异常
					if (args != null) {
						Object[] oParameters = new Object[args.length];
						for (int i = 0; i < args.length; i++) {
							if (Util.isNumeric(args[i])) {
								oParameters[i] = Util.parameters_String2Float(args[i]);
							} else {
								oParameters[i] = args[i];
							}
						}
						jsResult = JavaScript_parser.getScript(jsMethod,oParameters);
					}
				} else {
					System.out.println("");
					System.out.println("这个超链接<a>里没有window，有点号");
					jsResult = temp;
				}
			} else {

				System.out.println("");
				System.out.println("【getLink--isJavascriptLink()--not function】这个超链接<a>里有window");
				if (href.indexOf("window.close") > -1) {
					jsResult = "window.close()";
				}
				if ((href.indexOf("window") > -1) && (href.indexOf("=") > -1)) {
					int b1 = href.indexOf("=");
					jsResult = href.substring(b1 + 1).replaceAll("'", "")
							.replaceAll(";", "");
				}

				if ((href.indexOf("document") > -1) && (href.indexOf("=") > -1)) {
					int b1 = href.indexOf("=");
					jsResult = href.substring(b1 + 1).replaceAll("'", "")
							.replaceAll(";", "");
				}

			}
			if (jsResult != null) {
				Element url = new Element("url");
				url.setText(jsResult);
				a.addContent(url);

			}
		} else {// 不是以Javascript作为链接
			if ((href != null) && !(href.equals("")) && !(href.equals("#"))) {

				if (href.indexOf("window.close") > -1) {
					href = "window.close()";
				}
				if ((href.indexOf("window") > -1) && (href.indexOf("=") > -1)) {
					int b1 = href.indexOf("=");
					href = href.substring(b1 + 1).replaceAll("'", "");
				}

				if ((href.indexOf("document") > -1) && (href.indexOf("=") > -1)) {
					int b1 = href.indexOf("=");
					href = href.substring(b1 + 1).replaceAll("'", "");
				}

				Element url = new Element("url");
				url.setText(href);
				a.addContent(url);
			}

		}

		Element tx = new Element("nm");
		String result = ((LinkTag) link).getLinkText();
		if (result.indexOf("&lt;")>-1) {
			result = result.replaceAll("&lt;", "<");
		}
		if (result.indexOf("&lt")>-1) {
			result = result.replaceAll("&lt", "<");
		}
		if (result.indexOf("&gt;")>-1) {
			result = result.replaceAll("&gt;", ">");
		}
		if (result.indexOf("&gt")>-1) {
			result = result.replaceAll("&gt", ">");
		}

		tx.setText(result);
		a.addContent(tx);
		return a;
	}

	// 提取图片
	// public static Element getImage(ImageTag imageTag){
	// ImageTag image = imageTag;
	// Element img = new Element("img");
	// img.setText(image.extractImageLocn());
	// return img;
	// }

	// 提取图片
	public static Element getLabel2(LabelTag labelTag) {
		LabelTag label2 = labelTag;
		Element label = new Element("tx");
		label.setText(label2.getLabel());
		return label;
	}

	public static Element getSpan(Span spanTag, Element element) {
		Span span2 = spanTag;
		Element span_text = new Element("tx");
		NodeList spanList = span2.getChildren();
		String temp_text = "";
		if (spanList != null) {
			for (int i = 0; i < spanList.size(); i++) {
				Node node = spanList.elementAt(i);
				if (node instanceof TextNode) {
					String text = node.getText().trim()
							.replaceAll("&nbsp;", "");
					if ((text != null) && !(text.equals(""))) {
						temp_text += text;
					}
				} else if (node instanceof Span) {
					span_text = getSpan((Span) node, element);
				}
				// 处理输入表单<input>
				else if (node instanceof InputTag) {
					Element input = Input.getInput((InputTag) node, null);

					if (input != null) {
						element.addContent(input);
					}
				}
			}
		}
		if ((temp_text != null) && !(temp_text.equals(""))) {
			span_text.setText(temp_text);
		}
		return span_text;
	}

	public static void getP(ParagraphTag paragraph, Element e) {
		Element p = new Element("p");
		NodeList pList = paragraph.getChildren();
		for (int i = 0; i < pList.size(); i++) {
			Node node = pList.elementAt(i);
			if (node instanceof TextNode) {
				Element text = getText2((TextNode) node);
				if (text != null) {
					e.addContent(text);
				}
			} else if (node instanceof Span) {
				Element span = getSpan((Span) node, e);
				if (span != null) {
					e.addContent(span);
				} else {
					// p = null;
				}
			}
		}
	}

	// 提取多行文本域
	public static Element getTextarea(TextareaTag textareaTag) {
		TextareaTag textarea2 = textareaTag;
		Element textarea = new Element("ta");

		String name = textarea2.getAttribute("name");
		String id = textarea2.getAttribute("id");
		if ((name != null) && !(name.equals(""))) {
			textarea.setAttribute("nm", name);
		} else if ((id != null) && !(id.equals(""))) {
			textarea.setAttribute("nm", name);
		}

		Element txt = new Element("txt");
		txt.setText(textarea2.getValue());

		textarea.addContent(txt);

		return textarea;
	}

	// 提取嵌套Div
	public static void getDiv(Div divTag, Element e) throws Exception {
		Div div2 = divTag;
		Element div = new Element("div");
		NodeList nodeList = div2.getChildren();
		if (nodeList != null) {
			for (int i = 0; i < nodeList.size(); i++) {
				Node node = nodeList.elementAt(i);
				Node nextNode = null;
				if ((i + 1) < nodeList.size()) {
					nextNode = nodeList.elementAt(i + 1);
				}
				// 处理label
				if ((node instanceof LabelTag)) {

					Element label = getLabel2((LabelTag) node);
					if (label != null) {
						e.addContent(label);
					}
				}
				// 处理超链接
				else if (node instanceof LinkTag) {
					Element link = getLink((LinkTag) node);
					if (link != null) {
						e.addContent(link);
					}
				}
				// 处理输入表单input
				else if (node instanceof InputTag) {
					Element input = Input.getInput((InputTag) node, nextNode);

					if (input != null) {
						e.addContent(input);
					}
				}
				// 处理多行文本域textarea
				else if (node instanceof TextareaTag) {
					Element textarea = getTextarea((TextareaTag) node);
					e.addContent(textarea);
				}

				// 处理下拉列表
				else if (node instanceof SelectTag) {
					Element select = getSelect((SelectTag) node);
					e.addContent(select);
				}

				// 处理表格table
				else if (node instanceof TableTag) {
					if (getTable((TableTag) node) != null) {
						Element table = getTable((TableTag) node);
						e.addContent(table);
					}
				}

				// 处理div
				else if (node instanceof Div) {
					try {
						getDiv((Div) node, e);
					} catch (Exception ex) {
						ex.printStackTrace();
					}
				}

				else if (node instanceof Span) {
					Element span = getSpan((Span) node, e);
					if (span != null) {
						e.addContent(span);
					}
				}

				// 处理<p>
				else if (node instanceof ParagraphTag) {
					getP((ParagraphTag) node, e);
				}
				// 纯文本
				else if ((node instanceof TextNode)
						&& (!(node.getText().trim().equals("")))
						&& (!(nextNode instanceof InputTag))) {
					Element text = getText2((TextNode) node);
					e.addContent(text);
				}

				// 处理form
				else if (node instanceof FormTag) {
					Element form = getForm((FormTag) node);
					e.addContent(form);
				}

			}
		}

	}

	// 提取纯文本
	public static Element getText2(TextNode textNode) {
		TextNode text2 = textNode;
		Element text = new Element("tx");
		String result = text2.getText().trim().replaceAll(" ", "");
		if (result.indexOf("&lt;")>-1) {
			result = result.replaceAll("&lt;", "<");
		}
		if (result.indexOf("&lt")>-1) {
			result = result.replaceAll("&lt", "<");
		}
		if (result.indexOf("&gt;")>-1) {
			result = result.replaceAll("&gt;", ">");
		}
		if (result.indexOf("&gt")>-1) {
			result = result.replaceAll("&gt", ">");
		}
		if (result.indexOf("&nbsp;")>-1) {  //////////////////////////////////////
			result = result.replaceAll("&nbsp;", "");
		}
		if (result.indexOf(";")>-1) {  //////////////////////////////////////
			result = result.replaceAll(";", "");
		}

		if ((result != null) && !(result.equals(""))) {
			text.setText(result);
		} else {
			text = null;
		}
		return text;
	}

	// 提取下拉列表
	public static Element getSelect(SelectTag selectTag) {
		SelectTag select2 = selectTag;
		Element select = new Element("s");
		NodeList selectList = select2.getChildren();

		int option_count = select2.getOptionTags().length;
		select.setAttribute("v", String.valueOf(option_count));
		
		String sName = select2.getAttribute("name");
		if ((sName != null) && !(sName.equals(""))) {
			select.setAttribute("nm", sName);
		}
		for (int i = 0; i < selectList.size(); i++) {
			if (selectList.elementAt(i) instanceof OptionTag) {
				Element option = new Element("o");
				OptionTag optionTag = (OptionTag) selectList.elementAt(i);
				if (optionTag.getAttributeEx("selected") != null) {

				}

				String sValue = optionTag.getAttribute("value");
				if ((sValue != null) && !(sValue.equals(""))) {
					option.setAttribute("v", sValue);
				}
				
				

				option.setText(optionTag.getOptionText());
				select.addContent(option);
			}
		}
		return select;
	}

	// 提取form表单
	public static Element getForm(FormTag formTag) {
		FormTag form2 = formTag;
		Element form = new Element("form");
		NodeList nodeList = form2.getChildren();

		if (nodeList != null) {
			form = AllTags.doAllTags(nodeList, form);
		}
		if (form2.getAttribute("action") != null) {
			form.setAttribute("action", form2.getAttribute("action"));
			smt_url = form2.getAttribute("action");
		}
		if (form2.getAttribute("method") != null) {
			form.setAttribute("method", form2.getAttribute("method"));
		}
		form.setAttribute("key", key);
		return form;
	}
}